﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Xml;

namespace PriLib
{
    public static class Helper
    {
        public static void WriteXmlToFile(this XmlDocument doc, string path)
        {
            XmlWriterSettings settings = new XmlWriterSettings();
            //MARK:请注意XmlWriter的格式设置
            settings.Indent = true;
            settings.IndentChars = " ";
            settings.NewLineOnAttributes = false;
            settings.NewLineChars = Environment.NewLine;
            settings.Encoding = Encoding.UTF8;
            XmlWriter writer = XmlWriter.Create(path, settings);
            doc.WriteTo(writer);
            writer.Flush();
            writer.Close();
        }

        /// <summary>
        /// Convert chars to string
        /// </summary>
        /// <param name="chars"></param>
        /// <returns></returns>
        public static string ToRealString(this char[] chars)
        {
            return new string(chars);
        }
        /// <summary>
        /// Convert bytes to Hex string
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public static string PrintInHex(this byte[] bytes)
        {
            StringBuilder sb = new StringBuilder();
            foreach (var b in bytes)
            {
                var s = Convert.ToString(b, 16);
                if (s.Length == 1)
                {
                    s = "0" + s;
                }
                sb.Append(s);
            }
            return sb.ToString();
        }

        public static string ToBase64String(this byte[] bytes)
        {
            return Convert.ToBase64String(bytes);
        }

        /// <summary> 
        /// Convert Hex string to bytes
        /// </summary> 
        /// <param name="hexString"></param> 
        /// <returns></returns> 
        public static byte[] HexStringToBytes(this string hexString)
        {
            hexString = hexString.Replace(" ", "");
            if ((hexString.Length % 2) != 0)
                hexString += " ";
            byte[] returnBytes = new byte[hexString.Length / 2];
            for (int i = 0; i < returnBytes.Length; i++)
                returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
            return returnBytes;
        }


        /// <summary>
        /// Read a string in unicode, no matter what encode <param name="br">BinaryReader</param> is.
        /// </summary>
        /// <param name="br"></param>
        /// <returns></returns>
        public static string ReadUnicodeString(this BinaryReader br)
        {
            StringBuilder sb = new StringBuilder();
            long startPos = br.BaseStream.Position;
            var s = Encoding.Unicode.GetString(br.ReadBytes(2));
            while (s != "\0")
            {
                sb.Append(s);
                s = Encoding.Unicode.GetString(br.ReadBytes(2));
            }
            return sb.ToString();
        }

        /// <summary>
        /// Read a string in ASCII and end with 0x00, no matter what encode <param name="br">BinaryReader</param> is.
        /// </summary>
        /// <param name="br"></param>
        /// <returns></returns>
        public static string ReadSigleByteString(this BinaryReader br)
        {
            StringBuilder sb = new StringBuilder();
            long startPos = br.BaseStream.Position;
            var s = br.ReadChar();
            while (s != 0)
            {
                sb.Append(s);
                s = br.ReadChar();
            }
            return sb.ToString();
        }

        public static byte[] ReadToEnd(this BinaryReader br)
        {
            return br.ReadBytes((int) (br.BaseStream.Length - br.BaseStream.Position));
        }

        private static void TestReadUnicodeString()
        {
            var b = "6D0073002D0061007000700078003A002F002F00770069006E0064006F00770073002E00750069002E006C006F0067006F006E002F00".HexStringToBytes();
            var s = Encoding.Unicode.GetString(b);//OK
            b = Encoding.Unicode.GetBytes("\0");
            s = b.PrintInHex();//0000
        }
    }
}
